﻿/*
 * 14-10-2010 - George Kouwenhoven - 0862002        	  
 * 
 * View is de klasse die alle data bevat die de GUI nodig heeft om geupdatet te worden.
 * Om te voorkomen dat we allerlei klassen bij de GUI/Client moeten leggen,
 * wordt al deze data in een vereenvoudigde manier opgestuurd. Dit zou je ook wel serializen kunnen noemen,
 * maar dan een zelfbedachte implementatie. Bedank Mike voor deze uitstekende manier :) 
 */
using System.Collections.Generic;
using Roborally.CommonData.GlobaleTypes;
//using Roborally.GUI;
using Roborally.CommonData.Enums;

namespace Roborally.Server
{
    /// <summary>
    /// De klasse View. Zie de header voor veel meer informatie.
    /// </summary>
    public class View : IView
    {

        public void EindeSpel(string winnaarInfo)
        {
            string InfoDiePieterMoetHebbenAndersGaatHijHuilen;
            InfoDiePieterMoetHebbenAndersGaatHijHuilen = "Winnaar:" + winnaarInfo;
            //maak einde enum aan;
            Manager.Instance.VerstuurData(new BerichtType(),spelerId, InfoDiePieterMoetHebbenAndersGaatHijHuilen);
        }

        #region Property's & Fields
        private int spelerId;
        public int SpelerID { get { return spelerId; } }
        private bool BordVerstuurd = false;
        private List<IProgramKaart> kaartenVanSpeler;
        #endregion

        /// <summary>
        /// View Constructor met alleen de SpelerID die gebruikt wordt voor het aanmaken van een view per speler
        /// </summary>
        /// <param name="spelerId"></param>
        public View(int spelerId)
        {
            this.spelerId = spelerId;
        }

        /// <summary>
        /// Constructor van de View die het model per speler koppelt aan het modelgewijzigd event
        /// </summary>
        /// <param name="spelerId">De ID van een speler</param>
        /// <param name="model">Het model</param>
        public View(int spelerId, IModel model)
            : this(spelerId)
        {
            model.ModelGewijzigd += new ModelGewijzigdHandler(model_ModelGewijzigd);
        }


        /// <summary>
        /// Event handler voor model gewijzigd event vanuit model
        /// </summary>
        /// <param name="modelKloon"></param>
        private void model_ModelGewijzigd(ModelKloonHandler model)
        {
            IModel modelKloon = model();

            if (!BordVerstuurd)
            {
                string bordInfo = "";
                for (int i = 0; i < modelKloon.Vakken.GetLength(0); i++)
                {
                    for (int j = 0; j < modelKloon.Vakken.GetLength(1); j++)
                    {
                        //info verzamelen
                        #region Info verzamelen
                        int Actief = 0;
                        #region value bepalen
                        if (modelKloon.Vakken[i, j] != null)
                        {
                            if (modelKloon.Vakken[i, j].Actief(SpelerID))//letop hier hoort een beurtnummer ingevuld te worden...
                            {
                                Actief = 1;
                            }
                        #endregion

                            int CheckpointNummer = modelKloon.Vakken[i, j].CheckpointNummer();
                            #region value bepalen
                            if (CheckpointNummer == 0)
                            {
                                CheckpointNummer = -1;
                            }
                            #endregion

                            int BandType = -1;
                            #region value bepalen
                            BandType = (int)modelKloon.Vakken[i, j].KrijgBandType() + 1;
                            #endregion

                            int dimensie = -1;
                            #region value bepalen
                            if (modelKloon.Vakken[i, j].KrijgDimensie() == Dimensie.Horizontaal)
                            {
                                dimensie = 1;
                            }
                            else if (modelKloon.Vakken[i, j].KrijgDimensie() == Dimensie.Verticaal)
                            {
                                dimensie = 2;
                            }
                            #endregion

                            int draaiRichting = (int)modelKloon.Vakken[i, j].KrijgDraairichting();
                            #region value bepalen
                            //if (modelKloon.Vakken[i, j].KrijgDraairichting() == DraaiRichting.Links)
                            //{
                            //    draaiRichting = 1;
                            //}
                            //else if (modelKloon.Vakken[i, j].KrijgDraairichting() == DraaiRichting.Rechts)
                            //{
                            //    draaiRichting = 2;
                            //}
                            #endregion

                            int Kracht = modelKloon.Vakken[i, j].KrijgKracht();
                            #region value bepalen
                            if (Kracht == 0)
                            {
                                Kracht = -1;
                            }
                            #endregion

                            int LaserMond = 0;
                            #region value bepalen
                            if (modelKloon.Vakken[i, j].KrijgLaserMond())
                            {
                                LaserMond = 1;
                            }
                            #endregion

                            int muurBoven = 0;
                            int muurLinks = 0;
                            int muurOnder = 0;
                            int muurRechts = 0;
                            #region value bepalen
                            if (modelKloon.Vakken[i, j].KrijgMuur(Richting.Noord))
                            {
                                muurBoven = 1;
                            }
                            if (modelKloon.Vakken[i, j].KrijgMuur(Richting.Oost))
                            {
                                muurLinks = 1;
                            }
                            if (modelKloon.Vakken[i, j].KrijgMuur(Richting.Zuid))
                            {
                                muurOnder = 1;
                            }
                            if (modelKloon.Vakken[i, j].KrijgMuur(Richting.West))
                            {
                                muurRechts = 1;
                            }
                            #endregion

                            int richting = (int)modelKloon.Vakken[i, j].KrijgRichting();
                            #region value bepalen
                            //switch (modelKloon.Vakken[i, j].KrijgRichting())
                            //{
                            //    #region hele hoop cases
                            //    case Richting.Noord:
                            //        richting = 1;
                            //        break;
                            //    case Richting.Oost:
                            //        richting = 2;
                            //        break;
                            //    case Richting.Zuid:
                            //        richting = 3;
                            //        break;
                            //    case Richting.West:
                            //        richting = 4;
                            //        break;
                            //    #endregion
                            //}
                            #endregion

                            int type = -1;
                            #region value bepalen
                            switch (modelKloon.Vakken[i, j].KrijgType())
                            {
                                #region hele hoop cases
                                case VakType.Checkpoint:
                                    type = 1;
                                    break;
                                case VakType.Draaischijf:
                                    type = 2;
                                    break;
                                case VakType.Expresband:
                                    type = 3;
                                    break;
                                case VakType.Laser:
                                    type = 4;
                                    break;
                                case VakType.Leeg:
                                    type = 5;
                                    break;
                                case VakType.Lopendeband:
                                    type = 6;
                                    break;
                                case VakType.Pusher:
                                    type = 7;
                                    break;
                                case VakType.Reparatievak:
                                    type = 8;
                                    break;
                                case VakType.Valkuil:
                                    type = 9;
                                    break;
                                #endregion
                            }
                            #endregion
                        #endregion

                            bordInfo += i + ";" + j + ";" + type + ";" + richting + ";" + muurBoven + ";" + muurLinks + ";" + muurOnder + ";" + muurRechts + ";" + LaserMond + ";" + Kracht + ";" + draaiRichting + ";" + dimensie + ";" + BandType + ";" + CheckpointNummer + ";" + Actief + "^";//X,Y,Type,Richting,MuurBoven,MuurLinks,MuurOnder,MuurRechts,LaserMond,Kracht,DraaiRichting,Dimensie,BandType,CheckpointNummer,Actief
                        }
                    }
                }
                bordInfo = "TekenBord:" + bordInfo;
                Manager.Instance.VerstuurData(BerichtType.TekenBord, spelerId, bordInfo);
                //gui.Update(bordInfo);
                BordVerstuurd = true;
            }

            string spelersInfo = "";
            for (int i = 0; i < modelKloon.ModelSpelerInfos.Count; i++)
            {
                int robottype = (int)modelKloon.ModelSpelerInfos[i].RobotType;
                int richting = (int)modelKloon.ModelSpelerInfos[i].Richting;

                //eerste speler moet vooraan zodat gui weet welke speler het is
                if (modelKloon.ModelSpelerInfos[i].SpelerID == spelerId)
                {
                    //speler van de view als eerste
                    spelersInfo = modelKloon.ModelSpelerInfos[i].ToTransferString() + spelersInfo;
                    #region oude crap
                    //eersteSpeler = modelKloon.ModelSpelerInfos[i].ToTransferString();
                    //eersteSpeler += modelKloon.ModelSpelerInfos[i].SpelerID
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Naam
                    //    + ";" + robottype
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Schade
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Locatie.X
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Locatie.Y
                    //    + ";" + richting
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Levens
                    //    + ";" + Convert.ToInt32(modelKloon.ModelSpelerInfos[i].PowerDown)
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Checkpoints
                    //    + ";"; //open kaarten van programbay toevoegen
                    //for (int j = 0; j <= modelKloon.ModelSpelerInfos[i].KaartIndex; j++)
                    //{
                    //    eersteSpeler += (int)modelKloon.ModelSpelerInfos[i].ProgrammeerBaai[j].GetSoort()
                    //        + "$" + modelKloon.ModelSpelerInfos[i].ProgrammeerBaai[j].AantalStappen
                    //        + "$" + modelKloon.ModelSpelerInfos[i].ProgrammeerBaai[j].Prioriteit
                    //        + "@";
                    //}

                    //eersteSpeler += "^";
                    #endregion
                }

                else
                {
                    spelersInfo += modelKloon.ModelSpelerInfos[i].ToTransferString();
                    #region oude crap
                    //spelersInfo += modelKloon.ModelSpelerInfos[i].SpelerID
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Naam
                    //    + ";" + robottype
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Schade
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Locatie.X
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Locatie.Y
                    //    + ";" + richting
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Levens
                    //    + ";" + Convert.ToInt32(modelKloon.ModelSpelerInfos[i].PowerDown)
                    //    + ";" + modelKloon.ModelSpelerInfos[i].Checkpoints
                    //    + ";"; //open kaarten van programbay toevoegen

                    //for (int j = 0; j <= modelKloon.ModelSpelerInfos[i].KaartIndex; j++)
                    //{
                    //    spelersInfo += (int)modelKloon.ModelSpelerInfos[i].ProgrammeerBaai[j].GetSoort()
                    //        + "$" + modelKloon.ModelSpelerInfos[i].ProgrammeerBaai[j].AantalStappen
                    //        + "$" + modelKloon.ModelSpelerInfos[i].ProgrammeerBaai[j].Prioriteit
                    //        + "@";
                    //}

                    //spelersInfo += "^";
                    //spelers zijn te onderscheiden door de string op ^ te splitsen
                    //daarna splits je de string op ; om op een volgend int SpelerID, string Naam, int Robottype, int Schade, int X, int Y, int Richting, int levens, int powerdown, int checkpoints
                    #endregion
                }
            }
            spelersInfo = "UpdateSpelers:" + spelersInfo;
            Manager.Instance.VerstuurData(BerichtType.UpdateSpelers, spelerId, spelersInfo);
            //gui.Update(spelersInfo);
        }

        /// <summary>
        /// De methode die de uitgedeelde kaarten omzet naar een string en deze doorstuurt naar de Manager
        /// </summary>
        /// <param name="kaarten">De kaarten van de speler</param>
        public void DeelKaarten(List<IProgramKaart> kaarten)
        {
            kaartenVanSpeler = kaarten;
            string kaartenInfo = "";
            for (int i = 0; i < kaarten.Count; i++)
            {
                int soortKaart = (int)kaarten[i].GetSoort();
                #region correcte waarde setten
                //switch (kaarten[i].GetSoort())
                //{
                //    #region hele hoop cases
                //    case KaartSoort.Backup:
                //        soortKaart = 1;
                //        break;
                //    case KaartSoort.LinksDraaien:
                //        soortKaart = 2;
                //        break;
                //    case KaartSoort.RechtsDraaien:
                //        soortKaart = 3;
                //        break;
                //    case KaartSoort.Uturn:
                //        soortKaart = 4;
                //        break;
                //    case KaartSoort.Vooruit:
                //        soortKaart = 5;
                //        break;
                //    #endregion
                //}
                #endregion
                kaartenInfo += soortKaart + ";" + kaarten[i].AantalStappen + ";" + kaarten[i].Prioriteit + "^";
            }
            kaartenInfo = "DeelKaarten:" + kaartenInfo;
            Manager.Instance.VerstuurData(BerichtType.DeelKaarten, spelerId, kaartenInfo);
            //gui.Update(kaartenInfo);
        }

        /// <summary>
        /// Methode wordt door controller aangeroepen wanneer het spel afgelopen is
        /// </summary>
        /// <param name="winnaarSpelerID">ID van de winnende speler</param>
        public void EindeSpel(int winnaarSpelerID)
        {
            //Geef een ModelSpelerInfo aan gui
        }
    }
}